using System;
using System.Data;
using System.Configuration;
using System.Collections;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Web.UI.HtmlControls;
using TVT.UI.Helpers;
using System.Collections.Generic;
using TVT.Common.Exceptions;
using TVT.UI.EventArguments;
using TVT.Common.Helpers;
using TVT.BizLayer.Entities;

namespace TVT.UI.UserControls
{
    public partial class ListUsers : System.Web.UI.UserControl
    {
        public event EventHandler OnEditUser = null;
        public event EventHandler OnDeletedUser = null;

        public void DeletedUser(EventArgs args)
        {
            if (OnDeletedUser != null)
            {
                OnDeletedUser(this, args);
            }
        }

        public void EditUser(UserEventArgs args)
        {
            if (OnEditUser != null)
            {
                OnEditUser(this, args);
            }
        }

        protected void Page_Load(object sender, EventArgs e)
        {
            if (!Page.IsPostBack)
            {
                ViewState["SortExpression"] = "LastName DESC";
                gvUsers.PageSize = Int32.Parse(ConfigurationManager.AppSettings[WellKnownKeys.GridViewsPageSizeKey]);
                try
                {
                    BindData();                    
                }
                catch (FunctionalException ex)
                {
                    lblTransactionResultMessage.Text = ex.Message;
                }
            }
        }

        private void BindData()
        {          
             List<User> users;
             if (Roles.IsUserInRole(WellKnownKeys.AdministratorRolKey))
             {
                 users = User.FindAll();
             }
             else
             { //Rol: Admin can see only users from same company who are not master admin
                 User logUser = User.Find((Guid)Membership.GetUser().ProviderUserKey);
                 List<string> rolesOk = new List<string>();
                 foreach (string r in Roles.GetAllRoles())
                 {
                     if (r != WellKnownKeys.AdministratorRolKey)
                         rolesOk.Add(r);
                 }

                 users = User.FindAll();
             }

             if (users.Count == 0)
             {
                 lblTransactionResultMessage.Text = Resources.NoResultsFound;
                 lblTransactionResultMessage.Visible = true;
             }
             else
             {
                 lblTransactionResultMessage.Visible = false;
                 pnlSearchUsersResults.Visible = true;
             }

            gvUsers.DataSource = users;
            ViewState["SortableListUsers"] = users;
            gvUsers.DataBind();
        }

        protected void gvUsers_PageIndexChanging(Object sender, GridViewPageEventArgs e)
        {            
            gvUsers.PageIndex = e.NewPageIndex;
            if (gvUsers.EditIndex != -1)
            {      
                e.Cancel = true;             
                int newPageNumber = e.NewPageIndex + 1;                
            }
            else
            {
                DataView dataView = new DataView(GetDataTableFromUsersList((List<User>)ViewState["SortableListUsers"]));

                dataView.Sort = ViewState["SortExpression"].ToString();
                gvUsers.DataSource = dataView;
                gvUsers.DataBind();
            }

        }

        protected void OnSortingGvUsers(object sender, GridViewSortEventArgs e)
        {
            string sort = " DESC";

            if (ViewState["sortDirection"] == null)
                ViewState["sortDirection"] = SortDirection.Ascending;
            else
            {
                if ((SortDirection)ViewState["sortDirection"] == SortDirection.Ascending)
                {
                    ViewState["sortDirection"] = SortDirection.Descending;
                    sort = " DESC";
                }
                else
                {
                    ViewState["sortDirection"] = SortDirection.Ascending;
                    sort = " ASC";
                }
            }

            List<User> users = (List<User>)ViewState["SortableListUsers"];
            DataTable dataTable = GetDataTableFromUsersList(users);

            if (dataTable != null)
            {
                DataView dataView = new DataView(dataTable);

                dataView.Sort = e.SortExpression + sort;
                ViewState["SortExpression"] = e.SortExpression + sort;
                gvUsers.DataSource = dataView;
                gvUsers.DataBind();
            }
        }        

        private DataTable GetDataTableFromUsersList(List<User> users)
        {
            DataTable dataTable = new DataTable();

            dataTable.Columns.Add("UserId");
            dataTable.Columns["UserId"].DataType = System.Type.GetType("System.Guid");

            dataTable.Columns.Add("UserName");
            dataTable.Columns["UserName"].DataType = System.Type.GetType("System.String");

            dataTable.Columns.Add("Rol");
            dataTable.Columns["Rol"].DataType = System.Type.GetType("System.String");

            dataTable.Columns.Add("Email");
            dataTable.Columns["Email"].DataType = System.Type.GetType("System.String");

            dataTable.Columns.Add("FirstName");
            dataTable.Columns["FirstName"].DataType = System.Type.GetType("System.String");

            dataTable.Columns.Add("LastName");
            dataTable.Columns["LastName"].DataType = System.Type.GetType("System.String");

            dataTable.Columns.Add("Password");
            dataTable.Columns["Password"].DataType = System.Type.GetType("System.String");

            DataRow dataRow;

            foreach (User user in users)
            {
                dataRow = dataTable.NewRow();

                dataRow["UserId"] = user.UserId;
                dataRow["UserName"] = user.UserName;
                dataRow["LastName"] = user.LastName;
                dataRow["FirstName"] = user.FirstName;
                //string[] roles = Roles.GetRolesForUser(user.UserId.ToString());
                string[] roles = Roles.GetRolesForUser(user.UserName);
                dataRow["Rol"] = roles[0];
                dataRow["Email"] = user.Email;
                dataRow["Password"] = Membership.GetUser(user.UserId).GetPassword();

                dataTable.Rows.Add(dataRow);
            }

            return dataTable;
        }

        protected void gvUsers_RowDataBound(object sender, GridViewRowEventArgs e)
        {
            StylesApplier stylesApplier = new StylesApplier();
            Guid idUser = Guid.Empty;
            try
            {
                stylesApplier.GridViewStyle(e.Row);

                User user = null;
                user = ((User)(e.Row.DataItem));

                if ((user != null) && (user.UserId != Guid.Empty))
                {
                    idUser = user.UserId;

                    Label lblFirstName = (Label)e.Row.FindControl("lblFirstName");                        
                    user = ((User)(e.Row.DataItem));
                    lblFirstName.Text = user.FirstName;

                    Label lblLastName = (Label)e.Row.FindControl("lblLastName");
                    lblLastName.Text = user.LastName;

                    Label lblUserName = (Label)e.Row.FindControl("lblUserName");
                    lblUserName.Text = user.UserName;

                    Label lblEmail = (Label)e.Row.FindControl("lblEmail");
                    lblEmail.Text = user.Email;

                    Label lblRol = (Label)e.Row.FindControl("lblRol");
                    string[] roles = Roles.GetRolesForUser(user.UserName);
                    lblRol.Text = roles[0];
                   
                }
            }

            catch (Exception ex)
            {
                idUser = new Guid(((System.Data.DataRowView)(e.Row.DataItem)).Row.ItemArray[0].ToString());
                                
                Label lblFirstName = (Label)e.Row.FindControl("lblFirstName");
                lblFirstName.Text = ((System.Data.DataRowView)(e.Row.DataItem)).Row.ItemArray[1].ToString();

                Label lblRol = (Label)e.Row.FindControl("lblRol");
                lblRol.Text = ((System.Data.DataRowView)(e.Row.DataItem)).Row.ItemArray[2].ToString();

                Label lblEmail = (Label)e.Row.FindControl("lblEmail");
                lblEmail.Text = ((System.Data.DataRowView)(e.Row.DataItem)).Row.ItemArray[3].ToString();

                Label lblUserName = (Label)e.Row.FindControl("lblUserName");
                lblUserName.Text = ((System.Data.DataRowView)(e.Row.DataItem)).Row.ItemArray[4].ToString();

                Label lblLastName = (Label)e.Row.FindControl("lblLastName");
                lblLastName.Text = ((System.Data.DataRowView)(e.Row.DataItem)).Row.ItemArray[5].ToString();
               
            }

            if (idUser != Guid.Empty)
            {

                Label lblPass = (Label)e.Row.FindControl("lblPass");
                lblPass.Text = Membership.GetUser(idUser).GetPassword();

                ImageButton lbtnDelete = (ImageButton)e.Row.FindControl("lbtnDelete");
                lbtnDelete.CommandArgument = idUser.ToString();

                ImageButton lbtnEdit = (ImageButton)e.Row.FindControl("lbtnEdit");
                lbtnEdit.CommandArgument = idUser.ToString();
            }
        }

        protected void gvUsers_RowCommand(object sender, GridViewCommandEventArgs e)
        {
            string id = e.CommandArgument.ToString();

            if (e.CommandName == "DeleteUser")
            {
                lblTransactionResultMessage.Visible = true;
                
                try
                {
                    Guid userId = new Guid(id);
                    Guid usserIdLogged = (Guid)Membership.GetUser().ProviderUserKey;

                    User.Delete(new Guid(id));
                    BindData();
                    DeletedUser(new EventArgs());

                    //If the deleted is equal to the logged user
                    if (userId == usserIdLogged)
                    {
                        FormsAuthentication.SignOut();
                        Response.Redirect(Request.Url.AbsolutePath);                
                    }                    
                }
                catch (FunctionalException ex)
                {
                    lblTransactionResultMessage.Text = ex.Message;
                }
            }

            if (e.CommandName == "EditUser")
            {
                try
                {
                    UserEventArgs args = new UserEventArgs();
                    args.IdUser = new Guid(e.CommandArgument.ToString());
                    EditUser(args);
                }
                catch (FunctionalException ex)
                {
                    lblTransactionResultMessage.Text = ex.Message;
                }
            }
        }
    }
}